package com.yang.crawler.article.strategy;


import com.gargoylesoftware.htmlunit.html.*;
import com.yang.crawler.file.IFileUploader;
import com.yang.crawler.html.AbstractHtmlUnitTemplate;
import com.yang.crawler.strategy.IArticleCrawlStrategy;
import com.yang.crawler.strategy.annotations.ArticleCrawlStrategy;
import com.yang.crawler.strategy.dto.ArticleColumnCrawlDTO;
import com.yang.crawler.strategy.dto.ArticleCrawlDTO;
import com.yang.crawler.strategy.enums.ArticleCrawlWebsiteEnum;
import com.yang.crawler.strategy.request.ArticleColumnCrawlRequest;
import com.yang.crawler.strategy.request.ArticleCrawlRequest;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

@Component
@ArticleCrawlStrategy(website = ArticleCrawlWebsiteEnum.ZQ99299)
public class Zq99299Strategy implements IArticleCrawlStrategy {
    @Resource
    private IFileUploader localFileUploader;
    @Override
    public ArticleColumnCrawlDTO crawlArticleColumn(ArticleColumnCrawlRequest articleColumnCrawlRequest) {
        String columnUrl = articleColumnCrawlRequest.getColumnUrl();
        return new AbstractHtmlUnitTemplate<ArticleColumnCrawlDTO>(columnUrl) {
            @Override
            public ArticleColumnCrawlDTO handleHtmlPage(HtmlPage page) {
                ArticleColumnCrawlDTO articleColumnCrawlDTO = new ArticleColumnCrawlDTO();
                articleColumnCrawlDTO.setTitle(page.getTitleText());
                articleColumnCrawlDTO.setUrl(page.getBaseURI().toString());
                articleColumnCrawlDTO.setProtocol(page.getBaseURL().getProtocol());
                articleColumnCrawlDTO.setWebsite(page.getBaseURL().getHost());

                HtmlUnorderedList articleList = page.getFirstByXPath("//*[@id=\"app\"]/div[1]/main/div[1]/ul[1]");
                String preUrl = page.getBaseURL().getProtocol() + "://" + page.getBaseURL().getHost();

                for (DomElement domElement : articleList.getChildElements()) {
                    for (DomElement childElement : domElement.getChildElements()) {
                        if (childElement instanceof HtmlAnchor) {
                            HtmlAnchor htmlAnchor = (HtmlAnchor) childElement;
                            String articleTitle = htmlAnchor.getTextContent();
                            String articleUrl = preUrl + htmlAnchor.getHrefAttribute();
                            articleColumnCrawlDTO.putTitleAndLink(articleTitle, articleUrl);
                        } else if (childElement instanceof HtmlUnorderedList) {
                            HtmlUnorderedList unorderedList = (HtmlUnorderedList) childElement;
                            for (DomElement element : unorderedList.getChildElements()) {
                                HtmlListItem htmlListItem = (HtmlListItem) element;
                                HtmlAnchor htmlAnchor = ((HtmlAnchor)htmlListItem.getFirstElementChild());
                                String articleTitle = htmlAnchor.getTextContent();
                                String articleUrl = preUrl + htmlAnchor.getHrefAttribute();
                                articleColumnCrawlDTO.putTitleAndLink(articleTitle, articleUrl);
                            }
                        }
                    }
                }
                return articleColumnCrawlDTO;
            }
        }.reptile();
    }

    @Override
    public ArticleCrawlDTO crawlArticle(ArticleCrawlRequest articleCrawlRequest) {
        String columnTitle = articleCrawlRequest.getColumnTitle();
        String website = articleCrawlRequest.getWebsite();
        String articleUrl = articleCrawlRequest.getArticleUrl();

        return new AbstractHtmlUnitTemplate<ArticleCrawlDTO>(articleUrl) {
            @Override
            public ArticleCrawlDTO handleHtmlPage(HtmlPage page) {
                ArticleCrawlDTO articleReptileDTO = new ArticleCrawlDTO();
                articleReptileDTO.setLink(articleUrl);
                articleReptileDTO.setTitle(page.getTitleText());

                HtmlDivision htmlDivision = page.getFirstByXPath("//*[@id=\"app\"]/div[1]/main/div[1]");
                for (DomElement childElement : htmlDivision.getChildElements()) {
                    if (childElement instanceof HtmlParagraph) {
                        HtmlParagraph paragraph = (HtmlParagraph) childElement;
                        DomNodeList<HtmlElement> imgElements = paragraph.getElementsByTagName("img");
                        if (!imgElements.isEmpty()) {
                            for (HtmlElement imgElement : imgElements) {
                                HtmlImage image = (HtmlImage) imgElement;
                                String srcAttribute = image.getSrcAttribute();
                                String filename = srcAttribute.substring(srcAttribute.lastIndexOf("/") + 1);
                                String directory = website + File.separator + columnTitle + File.separator + articleReptileDTO.getTitle();
                                String imgPath = storeImage(directory, filename, image);
                                image.setAttribute("src", imgPath);
                            }
                        }
                    }
                }
                StringBuilder html = new StringBuilder();
                html.append("<html><head><meta charset=\"UTF-8\">");
                html.append("<style>");
                html.append("img{");
                html.append("max-width:100%;height:auto;}");
                html.append("</style>");
                html.append("</head>");
                html.append("<body>");
                html.append(htmlDivision.asXml());
                html.append("</body></html>");
                articleReptileDTO.setHtmlContent(html.toString());
                return articleReptileDTO;
            }
        }.reptile();
    }

    private String storeImage(String directory, String filename, HtmlImage image) {
        directory = "image" + File.separator + directory;
        String suffix = filename.substring(filename.lastIndexOf(".") + 1);
        filename = filename.replace(".", "");
        filename = filename.substring(0, filename.length() - suffix.length());
        filename = filename + "." + suffix;
        try (InputStream inputStream = image.getWebResponse(true).getContentAsStream()) {
            return localFileUploader.uploadFile(directory, filename, inputStream);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
}